package com.useeinfo.oa.modules.threadUtil.message;

import com.alibaba.fastjson.JSONObject;
import com.useeinfo.framework.sugar.tools.Configuration;
import com.useeinfo.oa.modules.base.biz.MessageBiz;
import com.useeinfo.oa.modules.base.entity.Enterprise;
import com.useeinfo.oa.modules.base.entity.Message;
import com.useeinfo.oa.modules.base.enums.MessageTypeEnum;
import com.useeinfo.oa.modules.base.vo.MessageVO;
import com.useeinfo.oa.modules.security.enums.DeviceType;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PushDeviceMessage extends Thread {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    private final static String LeanCloudAPI = "https://O1nhQd5g.push.lncld.net/1.1/push";
    private final static String applicationId = Configuration.getConfigurationByName("applicationId");
    private final static String clientKey = Configuration.getConfigurationByName("clientKey");
    private final static String masterKey = Configuration.getConfigurationByName("masterKey");

    private List<MessageVO> messageVOS;
    private String message;
    private MessageTypeEnum messageTypeEnum;
    private MessageBiz messageBiz;
    private String enterpriseId;
    private String code;

    public PushDeviceMessage(List<MessageVO> messageVOS, String message, MessageTypeEnum messageTypeEnum, MessageBiz messageBiz, String  enterpriseId,String code) {
        this.messageVOS = messageVOS;
        this.message = message;
        this.messageTypeEnum = messageTypeEnum;
        this.messageBiz = messageBiz;
        this.enterpriseId = enterpriseId;
        this.code = code;
    }


    @Override
    public synchronized void run() {
        if (CollectionUtils.isEmpty(messageVOS)) {
            return;
        }
        messageVOS.forEach(messageVO -> {
            try {
                logger.info("发送消息对应的人员Token:{}",messageVO.getDeviceToken());
                SendMessage(messageVO.getDeviceType(), messageVO.getDeviceToken());
            } catch (Exception e) {
                logger.info("发送异常：{}", e);
            }
        });
    }

    /**
     * 发送消息
     *
     * @param platform
     * @param clientid
     */
    @Transactional
    public void SendMessage(String platform, String clientid) {
        logger.info("开始发送");
        try {
            String type;
            if(DeviceType.android.getCode().equalsIgnoreCase(platform)){
                type=DeviceType.android.getCode();
            }else{
                type= DeviceType.ios.getCode();
            }
            String msgId = messageBiz.saveMessage(message, clientid, messageTypeEnum,enterpriseId,code,type,clientid);
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("X-LC-Id", applicationId);
            headers.put("X-LC-Key", masterKey + ",master");
            headers.put("Content-Type", "application/json");

            JSONObject json = new JSONObject();
            JSONObject wherejson = new JSONObject();
            JSONObject datajson = new JSONObject();

            if (DeviceType.android.getCode().equalsIgnoreCase(platform)) {
                wherejson.put("installationId", clientid);
                wherejson.put("deviceType", DeviceType.android.getCode());
//                wherejson.put("deviceProfile",Configuration.getConfigurationByName("deviceProfile"));
                datajson.put("alert", message);
                datajson.put("type",messageTypeEnum.getCode());
                datajson.put("id",msgId);
                datajson.put("sound","default");
                json.put("where", wherejson);
                json.put("data", datajson);
            } else {
                wherejson.put("deviceToken", clientid);
                wherejson.put("deviceType", DeviceType.ios.getCode());
//                wherejson.put("deviceProfile",Configuration.getConfigurationByName("deviceProfile"));
                datajson.put("alert", message);
                datajson.put("type",messageTypeEnum.getCode());
                datajson.put("id",msgId);
                datajson.put("sound","default");
                json.put("where", wherejson);
                json.put("data", datajson);
                json.put("prod", "prod");
            }
            String result = HttpsUtil.Post(LeanCloudAPI, json.toJSONString(), "UTF-8", headers);
            logger.info("推送信息结果：{}", result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static class HttpsUtil {

        private static class TrustAnyTrustManager implements X509TrustManager {

            public void checkClientTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[]{};
            }
        }

        private static class TrustAnyHostnameVerifier implements HostnameVerifier {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        }

        /**
         * post方式请求服务器(https协议)
         *
         * @param url     请求地址
         * @param content 参数
         * @param charset 编码
         * @return
         * @throws NoSuchAlgorithmException
         * @throws KeyManagementException
         * @throws IOException
         */
        public static String Post(String url, String content, String charset, Map<String, String> headers)
                throws NoSuchAlgorithmException, KeyManagementException,
                IOException {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[]{new TrustAnyTrustManager()},
                    new java.security.SecureRandom());

            URL console = new URL(url);
            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.setDoOutput(true);
            for (String key : headers.keySet()) {
                conn.setRequestProperty(key, headers.get(key));
            }
            conn.connect();
            DataOutputStream out = new DataOutputStream(conn.getOutputStream());
            out.write(content.getBytes(charset));
            // 刷新、关闭
            out.flush();
            out.close();
            InputStream is = conn.getInputStream();
            if (is != null) {
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = is.read(buffer)) != -1) {
                    outStream.write(buffer, 0, len);
                }
                is.close();
                return outStream.toString();
            }
            return null;
        }

    }

    public static void main(String[] args) {
        try {
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("X-LC-Id", "1RimEhbY4rKCQgKewBJE9ak8-9Nh9j0Va");
            headers.put("X-LC-Key", "mebQM3y5EdUWSanryeK9YNcT,master");
            headers.put("Content-Type", "application/json");

            JSONObject json = new JSONObject();
            JSONObject wherejson = new JSONObject();
            JSONObject datajson = new JSONObject();
            wherejson.put("installationId", "68e5f2d77e6e5015d4d8d19778d05c5a");
            wherejson.put("deviceType", DeviceType.android.getCode());
            datajson.put("alert", "111");
            json.put("where", wherejson);
            json.put("data", datajson);
            String s = HttpsUtil.Post(LeanCloudAPI, json.toJSONString(), "UTF-8", headers);
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
